/* -*- mode: c++ -*- */
#ifndef ERROR_H_
#define ERROR_H_

#ifndef TOKEN_H_
#include "token.h"
#endif

#if 0
// TTokenId - need integer to have a distinct type
struct  TTokenId
    {
    TTokenId(int num) : Id(num){};
    int Id;
    };
#endif

// ErrorArg - helper class for polymorphizing Error() arguments.
class   ErrorArg
    {
public:
    ErrorArg(TTokenIndex Id)      : TokenId(Id), Int(0)  {};
    ErrorArg(const char* S)       : TokenId(), Str(S), Int(0)           {};
    ErrorArg(const std::string S) : TokenId(), Str(S), Int(0)     {};
    ErrorArg(int Val)       : TokenId(), Str(nullptr), Int(Val)   {};
    ErrorArg()              : TokenId(), Str(nullptr), Int(-1)    {};
    friend class TError;
private:
    TTokenIndex     TokenId;
    string          Str;
    int             Int;
    int             Color = -1;
    };

// TError - primary exception object
class   TError
    {
public:
    TError(string Name_) : Name(Name_) {};
   ~TError() {};
    string  GetName() { return Name; }
    void    Put(string Name, ErrorArg Arg);
    void    WriteToFile(unique_ref<TTokens> Tokens, FILE* Output);
    void    WriteToConsole();
    string  WriteToHtml();
private:
    void    ParseError(const char* Rover, string Name);
    void    ParseErrorString(const char*& Rover);
    void    GetElement(const char*&Rover);
    string  Name;
    enum Com { SHOW, TOKEN, TAG, TAGSTART, TAGEND, PUTARG, LITERAL };

    struct ErrorCommand
        {
        ErrorCommand(enum Com Command_, string Literal_)
            : Command(Command_), Literal(Literal_) {}
        enum Com    Command;
        string      Literal;
        };
    vector<ErrorCommand>    Commands;
    map<string, unique_ptr<vector<ErrorArg>>> Values;
    };

unique_ptr<TError>  ErrorNew(string Name);
//void                ErrorPut(unique_ref<TError> Error, string Name, ErrorArg Arg);
void                Error(unique_ptr<TError> Ptr);
void                Error(string Name);
void                Error(string Name,
                          string Param1, ErrorArg Arg1
                          );
void                Error(string Name,
                          string Param1, ErrorArg Arg1,
                          string Param2, ErrorArg Arg2
                          );
void                Error(string Name,
                          string Param1, ErrorArg Arg1,
                          string Param2, ErrorArg Arg2,
                          string Param3, ErrorArg Arg3
                          );
void                Error(string Name,
                          string Param1, ErrorArg Arg1,
                          string Param2, ErrorArg Arg2,
                          string Param3, ErrorArg Arg3,
                          string Param4, ErrorArg Arg4
                          );

#endif
